namespace GGF
{
    using API;

    namespace REST
    {
        using System;
        using System.Net;
        using System.Diagnostics;

        /// <summary>
        /// Class that allows user to create objects encapsulating a user's login
        /// credentials in the two ways supported by the gubb API: an API key, or HTTP
        /// Basic Authentication. The latter process uses a <see cref="System.Net.NetworkCredential"/>
        /// object to set headers in the actual request to the API: <see cref="GGF.REST.gRequest"/>.
        /// </summary>
        public class gCred
        {
            #region Fields

            char[] delims = { ' ' };
            string[] parsedKeyOrNamePassPair;
            bool flagKeyAPI;
            
            #endregion Fields

            #region Constructors

            /// <summary>
            /// Constructor for a specialized credentials object for use
            /// by GGF and eventual submission to gubb API via a <see cref="GGF.REST.gRequest"/>.
            /// </summary>
            /// <param name="isAPIkey">A standard .NET bool which sets the
            /// object's key status: Does this GGF credentials object encapsulate
            /// an API key (true) or a name/password pair (false)?</param>
            /// <param name="rawKeyOrNamePassPair">A standard .NET string which
            /// is the API key or name/password pair (separated by a space) for use
            /// in authenticating against the gubb API.</param>
            /// <returns>A "request-ready" GGF credentials object that
            /// has either the API key or name/password pair stored in
            /// the <c>parsedKeyOrNamePassPair</c> member.</returns>
            public gCred(bool isAPIkey, string rawKeyOrNamePassPair)
            {          
                flagKeyAPI = isAPIkey;
              
                parsedKeyOrNamePassPair = rawKeyOrNamePassPair.Split(delims);

                Debug.WriteLine("New credential set instantiated for received string " + rawKeyOrNamePassPair, "Credential creation");
            }

            #endregion Constructors

            #region Properties

            ///<summary>
            ///Returns true if credential object encapsulates API key. False if name/password.
            ///</summary>
            /// <value>
            /// Allows user to get a Boolean variable indicating whether or not
            /// this object encapsulates API key authentication. Setting only
            /// allowed internally.
            /// </value>
            public bool isAPIkey
            {
                get { return flagKeyAPI; }
                internal set { flagKeyAPI = value; }
            }

            #endregion Properties

            #region Methods

            /// <summary>
            /// Returns API key that this object encapsulates for authentication against API.            
            /// </summary>
            /// <returns>This object's API key (if it was constructed in that way).</returns>
            /// <exception cref="System.InvalidOperationException">Thrown when user asks
            /// object to return its API key, when it was constructed for use with a username
            /// and password (HTTP Basic Authentication).</exception>
            public string getAPIkey()
            {              
                    if (!isAPIkey)
                        throw new InvalidOperationException("Object designated as name/pass pair, not monolithic key");
                    else
                        return parsedKeyOrNamePassPair[0];               
            }

            /// <summary>
            /// Returns username/password that this object encapsulates for authentication against API.            
            /// </summary>
            /// <returns>This object's username/password pair (if it was constructed in that way).
            /// Represented internally by a <see cref="System.Net.NetworkCredential"/> object.</returns>
            /// <exception cref="System.InvalidOperationException">Thrown when user asks
            /// object to return its username and password for HTTP Basic Authentication,
            /// when it was constructed for use with an API key.</exception>
            public NetworkCredential getNamePass()
            {
                if (isAPIkey)
                    throw new InvalidOperationException("Object designated as monolithic key, not name/pass pair.");
                else
                {
                    if (parsedKeyOrNamePassPair.Length != 2)
                        throw new ArgumentException("Improperly formatted name/pass pair. Pair must be separated by one space ONLY");
                    else
                        return new NetworkCredential(parsedKeyOrNamePassPair[0], parsedKeyOrNamePassPair[1]);
                }
            }

            #endregion Methods
        }
    }
}